﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;

namespace 请求响应加密.Tools
{
    public class MapperHelper
    {
        private static IMapper _mapper;
        private static MapperConfiguration _configuration;

        /// <summary>
        /// 初始化AutoMapper配置
        /// </summary>
        /// <param name="configure">自定义配置动作</param>
        /// <param name="profiles">要注册的Profile集合</param>
        public static void Initialize(Action<IMapperConfigurationExpression> configure = null, params Profile[] profiles)
        {
            _configuration = new MapperConfiguration(cfg =>
            {
                // 添加自定义配置
                configure?.Invoke(cfg);

                // 添加Profile
                if (profiles?.Length > 0)
                {
                    foreach (var profile in profiles)
                    {
                        cfg.AddProfile(profile);
                    }
                }

                // 允许空集合映射
                cfg.AllowNullCollections = true;
            });

            // 验证映射配置
            //_configuration.AssertConfigurationIsValid();

            _mapper = _configuration.CreateMapper();
        }

        /// <summary>
        /// 将对象映射为指定类型
        /// </summary>
        public static TDestination MapTo<TDestination>(object source)
        {
            if (source == null)
                return default;

            return _mapper.Map<TDestination>(source);
        }

        /// <summary>
        /// 将对象映射到现有目标对象
        /// </summary>
        public static TDestination MapTo<TSource, TDestination>(TSource source, TDestination destination)
        {
            if (source == null)
                return destination;

            return _mapper.Map(source, destination);
        }

        /// <summary>
        /// 将集合映射为指定类型集合
        /// </summary>
        public static List<TDestination> MapToList<TDestination>(IEnumerable<object> source)
        {
            if (source == null)
                return new List<TDestination>();

            return _mapper.Map<List<TDestination>>(source);
        }


        /// <summary>
        /// 将源对象映射到目标类型，支持条件映射
        /// </summary>
        public static TDestination MapTo<TSource, TDestination>(TSource source,Action<IMappingOperationOptions<TSource, TDestination>> opts)
        {
            if (source == null)
                return default;

            return _mapper.Map(source, default(TDestination), opts);
        }

        /// <summary>
        /// 将源对象映射到目标类型，支持条件映射和自定义解析
        /// </summary>
        public static TDestination MapTo<TSource, TDestination>(TSource source, Dictionary<Expression<Func<TDestination, object>>, object> additionalMappings)
        {
            if (source == null)
                return default;

            var destination = _mapper.Map<TDestination>(source);

            if (additionalMappings != null)
            {
                foreach (var mapping in additionalMappings)
                {
                    var prop = (mapping.Key.Body as MemberExpression)?.Member as System.Reflection.PropertyInfo;
                    prop?.SetValue(destination, mapping.Value);
                }
            }

            return destination;
        }
    }
}
